<template>
  <middle-song ref="middle" @group-selected="getData"/>
  <div class="content" id="amap" ref="three">
    <!-- <left-song ref="left" /> -->
    <!-- <right-song ref="right" /> -->
    <!-- 设备详细信息 -->
    <DeviceDetailDialog ref="deviceDetailDialogRef" @update-icon="updateDeviceIcon" />
  </div>
</template>

<script lang="ts" setup>
// 左中右3部分内容
import LeftSong from './threeSong/left.vue'
import MiddleSong from './threeSong/middle.vue'
import RightSong from './threeSong/right.vue'
// 地图
import AMapLoader from "@amap/amap-jsapi-loader"
import DeviceDetailDialog from './components/DeviceDetailDialog.vue'
import { devicePropertyLogs, getDevicesList } from './api/devices.api'
// 引入公共方法获取设备属性
import { getDeviceProperties, getDeviceIconPath } from '@/utils/deviceUtils'

const deviceDetailDialogRef =ref()

// 设备数据
const deviceData = ref<any[]>([])

const currentDevice = reactive({
  deviceCustomName: '',
  deviceName: '',
  group: {},
  productKey: '',
  product: {
    name: '',
    nodeType: 0,
  },
  online: false,
  locate: {
    latitude: 0,
    longitude: 0,
  }
})
const stateDialog = reactive({
  show: false,
  row: {} as any,
  sw: 0,
  sl: 0,
  historyTime: [new Date(new Date().getTime() - 24 * 3600 * 1000), new Date(new Date().getTime() + 24 * 3600 * 1000)],
  swName: '',
  slName: '',
  gwmac: '', // 微自然
})

// // 定义地图实例
const map = ref<AMap.Map | null>(null)
let loadedAMap // 存储加载后的 AMap 对象

// 初始化地图
const init = async () => {
  // 使用 AMapLoader 加载高德地图 JS API
  loadedAMap = await AMapLoader.load({
    key: '6be4bdf50e7706f9eca082c41941578e',
    version: '2.0',
    plugins: [], // 可以根据需要添加插件
  })

  // 选取第一个设备作为地图中心点，如果没有设备数据则使用默认值
  let center = [114.383632, 22.717733]
  if (deviceData.value.length > 0) {
    // 计算所有设备经纬度的平均值
    let totalLongitude = 0
    let totalLatitude = 0
    deviceData.value.forEach(device => {
      totalLongitude += device.locate.longitude
      totalLatitude += device.locate.latitude
    })
    const avgLongitude = totalLongitude / deviceData.value.length
    const avgLatitude = totalLatitude / deviceData.value.length

    // 找出距离平均值最近的设备
    let closestDevice = deviceData.value[0]
    let minDistance = Math.sqrt(
      Math.pow(closestDevice.locate.longitude - avgLongitude, 2) +
      Math.pow(closestDevice.locate.latitude - avgLatitude, 2)
    )
    deviceData.value.forEach(device => {
      const distance = Math.sqrt(
        Math.pow(device.locate.longitude - avgLongitude, 2) +
        Math.pow(device.locate.latitude - avgLatitude, 2)
      )
      if (distance < minDistance) {
        minDistance = distance
        closestDevice = device
      }
    })
    // 使用最中心设备的经纬度作为地图中心点
    center = [closestDevice.locate.longitude, closestDevice.locate.latitude]
  }
  // 创建地图
  map.value = new loadedAMap.Map('amap', {
    center: center, // 初始化地图中心点
    zoom: 17, // 初始化地图缩放级别
  })
  
  // 遍历设备数据，创建标记
  if (deviceData.value.length > 0) {
    deviceData.value.forEach(device => {
      let switchState: number | undefined 
      let iconPath = getDeviceIconPath(device.productKey, device.online, switchState)

      const marker = new loadedAMap.Marker({
        position: [device.locate.longitude, device.locate.latitude],
        // 设置锚点为中心，使图片底部中心与经纬度坐标重合
        anchor: 'bottom-center', 
        icon: new loadedAMap.Icon({
          image: iconPath,
          size: new loadedAMap.Size(48, 48),
          // 确保图片无偏移
          imageOffset: new loadedAMap.Pixel(0, 0) 
        }),
        // title: `${device.name} - ${device.id}`, // 鼠标移入时显示设备名称和编号
        cursor: 'pointer',
      })

      // 弹出框样式，使用类似ECharts的风格
      const infoWindow = new loadedAMap.InfoWindow({
        content: `
          <ul>
            <li>设备名称： ${device.deviceCustomName ? device.deviceCustomName : '未命名设备'}</li>
            <li>设备编号： ${device.deviceName}</li>
            <li>设备状态： <span style="color: ${device.online ? '#83efea' : '#ffb340'}">${device.online ? '在线' : '离线'}</span></li>
          </ul>
          `,
        offset: new loadedAMap.Pixel(0, -50), // 控制弹框位置
      })

      // 鼠标移入显示设备信息
      marker.on('mouseover', () => {
        infoWindow.open(map.value!, marker.getPosition())
      })

      // 鼠标移开时隐藏弹出框
      marker.on('mouseout', () => {
        infoWindow.close()
      })

      // 点击标记时，地图放大并居中
      marker.on('click', () => {
        // 设置当前设备信息
        Object.assign(currentDevice, device)
        // 打开点击的详细信息弹窗
        deviceDetailDialogRef.value.openDialog(currentDevice)
        map.value!.setCenter([device.locate.longitude, device.locate.latitude]) // 设置地图中心点
        map.value!.setZoom(30) // 设置地图最大缩放级别
      })

      marker.setMap(map.value) // 将标记添加到地图上
      device.marker = marker // 保存标记引用，方便后续更新图标
    })
  } else {
    console.log('设备数据为空，无法创建标记')
  }

  // 对所有在线设备异步查询开关状态
  const onlineDevices = deviceData.value.filter(device => device.online)
  for (const device of onlineDevices) {
    await new Promise((resolve) => {
      stateDialog.row = device
    
      const { swName, slName, gwmac } = getDeviceProperties(device.productKey)
      stateDialog.swName = swName
      stateDialog.slName = slName
      // 单独处理微自然单灯控制器的 gwmac
      stateDialog.gwmac = device.productKey === 'hATm2Tswh3TDik8W' ? device.parentId : gwmac
      
      swHistory().then(() => {
        const iconPath = getDeviceIconPath(device.productKey, device.online, stateDialog.sw)
        device.marker.setIcon(new loadedAMap.Icon({
          size: new loadedAMap.Size(48, 48),
          imageOffset: new loadedAMap.Pixel(0, 0),
          image: iconPath,
          // 设置锚点为底部中心
          anchor: 'bottom-center', 
        }))
        resolve(null)
      })
    })
  }
}

// 更新设备图标
const updateDeviceIcon = (switchState: number) => {
  const iconPath = getDeviceIconPath(currentDevice.productKey, currentDevice.online, switchState)
  
  stateDialog.row.marker.setIcon(new loadedAMap.Icon({
    size: new loadedAMap.Size(48, 48), 
    imageOffset: new loadedAMap.Pixel(0, 0),
    image: iconPath,
    // 设置锚点为底部中心
    anchor: 'bottom-center',
  }))
}

// 开关历史数据
const swHistory = () => {
  var end = stateDialog.historyTime[1]
  var start = stateDialog.historyTime[0]
  // 返回一个 Promise 对象
  return devicePropertyLogs({
    deviceId: stateDialog.row.deviceId,
    name: stateDialog.swName,
    start: start.getTime(),
    end: end.getTime(),
  }).then((res) => {
    if (res.data && res.data.length > 0) {
      stateDialog.sw = Number(res.data[0].value)
    } else {
      stateDialog.sw = 0
    }
  })
}

const getData = async (groupId) => {
  await getDevicesList({
    pageSize: 999,
    pageNum: 1,
    group: groupId ? groupId : '',
  }).then((res) => {
    // 筛选出 locate 中 longitude 和 latitude 不为空的数据
    deviceData.value = res.data.rows.filter(device => {
      return device.locate && device.locate.longitude && device.locate.latitude
    })
    init()
  })
}

onMounted(async () => {
  await getData('')
})
</script>

<style lang="scss" scoped>
.content {
  width: 100%;
  flex: 1 1 auto;
  overflow: auto;
  display: flex;
  flex-direction: column; // 让子元素垂直排列
  justify-content: space-between;
  position: relative;
  z-index: -1;
}
:deep(.amap-info-content) {
  background: rgba(9, 14, 18, 0.8);
  color: rgb(255, 255, 255); 
  padding: 15px; 
  border-radius: 4px; 
  box-shadow: rgba(0, 0, 0, 0.8) 1px 2px 10px;
  font-family: "Microsoft YaHei"; 
  font-size: 16px;
  > ul {
    list-style-type: none;
    padding: 0;
    margin:  0 5px 0 0;
    > li:not(:last-child) {
      margin-bottom: 5px; 
    }
  }
  // 隐藏‘×’关闭符号
  > a {
    display: none;
  }
}
:deep(.amap-info-sharp) {
  border-top: 8px solid rgba(9, 14, 18, 0.8);
}
</style>
